﻿using System;

/*代表一条完整的蛇*/
public class Snake
{
    /*蛇节点组，存储蛇的所有节点*/
    public SnakeBodyBlock[] snakeBody;
    /*记录蛇包含的节点数量*/
    public int currentLength { get; private set; } = 0;
    /*表示蛇节点的字符*/
    public char bodyElement;
    /*蛇存在的屏幕空间的屏幕宽度与高度*/
    public int screenWidth;
    public int screenHeight;

    /*构造函数，生成初始蛇*/
    public Snake(int width, int height, char bodyElement, int initX, int initY, int targetLength)
	{
        this.bodyElement = bodyElement;
        screenHeight = height;
        screenWidth = width;

        //在初始位置生成第一个蛇节点
		snakeBody = new SnakeBodyBlock[width * height];
		snakeBody[0] = new SnakeBodyBlock(initX, initY, this.bodyElement, ESnakeDirection.Up);
        currentLength = 1;

        //添加节点，直到蛇节点数量达到目标长度
        if(targetLength > currentLength)
        {
            int growNum = targetLength - currentLength;
            for (int i = growNum; i > 0; i--)
            {
                Grow(false);
            }
        }
	}

    /*添加新的蛇节点到，可选择添加在蛇的头前或尾后*/
	public void Grow(bool atHead = true)
    {
        if (atHead)
        {
            //在蛇的头部前方生长
            SnakeBodyBlock newHead = snakeBody[0].GetNewBlock(true);
            newHead.PortalPosition(screenWidth, screenHeight);
            for(int i = currentLength; i >= 0; i--)
            {
                if(i == 0)
                {
                    snakeBody[0] = newHead;
                }
                else
                {
                    snakeBody[i] = snakeBody[i - 1];
                }
            }
        }
        else
        {
            //在蛇的尾部后方生长
            SnakeBodyBlock newTail = snakeBody[currentLength - 1].GetNewBlock(false);
            newTail.PortalPosition(screenWidth, screenHeight);
            snakeBody[currentLength] = newTail;
        }

        currentLength++;
    }

    /*修改蛇头（蛇节点组中的第一个节点）的前方方向*/
    public void SetDirection(ESnakeDirection direction)
    {
        if(currentLength <= 0)
        {
            return;
        }
        SnakeBodyBlock head = snakeBody[0];
        if(head == null)
        {
            return;
        }
        head.aheadDirection = direction;
    }

    /*调用此方法，蛇会前进一个单位*/
    public void Move()
    {
        SnakeBodyBlock headTarget = snakeBody[0].GetNewBlock(true);
        headTarget.PortalPosition(screenWidth, screenHeight);
        for (int i = currentLength-1; i >= 0; i--)
        {
            if(i == 0)
            {
                snakeBody[0] = headTarget;
            }
            else
            {
                snakeBody[i] = snakeBody[i - 1];
            }
        }
        
    }

    /*使用遍历方式，检查并更新蛇节点数量*/
    public void UpdateCurrentLength()
    {
        for(int i = 0; i < snakeBody.Length; i++)
        {
            if (snakeBody[i] == null)
            {
                currentLength = i;
                return;
            }
            else
            {
                continue;
            }
        }
    }
}
